﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web.Mvc;
using MethodWorx.CMS.Plugins;
using MethodWorx.CMS.Services;
using MethodWorx.CMS.Content;
using MethodWorx.CMS.UI.Application.ActionResults;

namespace MethodWorx.CMS.Workflow
{
    public abstract class WorkflowConfigurationController<TConfig> : Controller
        where TConfig: class
    {
        private IdeExtension view;
        private WorkflowService service;

        public WorkflowConfigurationController(IdeExtension view, WorkflowService service)
        {
            this.view = view;
            this.service = service;
        }

        private WorkflowConfigurationStep Step(Page instance, string workflowName, Guid? stepId, Guid? parentStepId, string output)
        {
            var workflow = instance.GetWorkflowConfiguration(true).FirstOrDefault(w => w.Name.ToLower() == workflowName.ToLower());
            if (workflow != null)
            {
                if (stepId == null)
                {
                    Guid id = Guid.NewGuid();
                    return this.CreateNewWorkflowConfigurationStep(id, output);
                }
                else
                {
                    var step = workflow.FindStep(stepId.Value);
                    if(step != null)
                        this.ReconfigureExistingStep(step, output);
                    return step;
                }
            }

            return null;
        }

        [HttpGet]
        public ActionResult Invoke(Page instance, string workflow, Guid? stepId, Guid? parentStepId)
        {
            var step = Step(instance, workflow, stepId, parentStepId, null);
            OnInvokeGet(instance, step);
            this.ViewData["output"] = step.Output;


            return new EmbeddedViewResult(view.WebEditor, this.ViewData, step.ComponentConfiguration);
        }

        protected virtual void OnInvokeGet(Page instance, WorkflowConfigurationStep step)
        {
        }

        [HttpPost]
        public ActionResult Invoke(Page instance, string workflow, string submit, Guid? stepId, Guid? parentStepId, string output)
        {
            var model = Step(instance, workflow, stepId, parentStepId, output);

            OnInvokePost(instance, model);
            this.ViewData["output"] = model.Output;

            this.TryUpdateModel<TConfig>((TConfig)model.ComponentConfiguration);

            if ((submit ?? "").ToLower() == "cancel")
                return new CloseDialogResult();

            if (ModelState.IsValid)
            {
                //
                //  ok, everything is ok, we need to save the workflow
                this.service.SaveWorkflow(instance, workflow, stepId, parentStepId, model);
                return new CloseDialogResult("saved");
            }

            return new EmbeddedViewResult(view.WebEditor, this.ViewData, model.ComponentConfiguration);
        }

        protected virtual void OnInvokePost(Page instance, WorkflowConfigurationStep model)
        {

        }


        protected abstract WorkflowConfigurationStep CreateNewWorkflowConfigurationStep(Guid id, string output);

        protected virtual void ReconfigureExistingStep(WorkflowConfigurationStep step, string output)
        {

        }
    }
}
